Current business-to-business (B2B) messaging systems have various ways to transparently handle stacked transactions. In one such system, a stack counter is incremented each time a transaction is started, and decremented when a commit or rollback method is called for the transaction. If a transaction already exists, the persistence infrastructure for the system will not initiate a new transaction. If the stack counter reaches zero, the transaction is committed or rolled back.
A business workflow component, such as a business process management (BPM) component, can execute B2B code at various locations. BPM components can be based on Enterprise JavaBeans (EJBs), and can be utilized in an EJB container-managed transaction. However, it is not possible for an existing B2B system to hold a transaction across a network “send”. Since the end receiving the send may be experiencing performance or network problems, or may just be slow in responding, the B2B system needs to commit the transaction promptly to avoid transaction timeouts. There are also circumstances, such as collocation or third party interoperability cases, where a message can come back into a Java virtual machine (JVM) initiating the send, encounter locks already being held, and result in a deadlock. Since the BPM component has an outstanding EJB transaction, it is not possible for B2B to commit the transaction without violating the constraints of the EJB container.
To resolve this problem, B2B can suspend the BPM transaction and start a new transaction when BPM calls into the B2B layer. B2B can commit when needed, before returning control to BPM, and can resume the BPM transaction. This leads to certain problems, as the suspended BPM transaction is more likely to timeout when resumed, even though the B2B transaction will not timeout. Further, beginning and committing a B2B transaction in the middle of an uncompleted BPM transaction can leave an integration system in an inconsistent state in the event of a system crash. Recovery under these circumstances is not possible.
Persistence is maintained in such systems by using a “shadow” copy of an object. Any changes to be made to an object during a transaction is first done to this shadow copy. If all the changes are processed successfully, the changes are applied to the original copy of the object. If such a system crashes during processing, or if the processing is otherwise unable to complete, the original copy remains unmodified. When the system comes back up, the processing is started again. One undesirable attribute to such an approach is the need for two copies of each object in existence while that object is being processed. This can be a significant drain on system resources, depending on the number of objects and type(s) of operations being conducted.